/**
在 Webpack 中，使用 CDN（内容分发网络）进行分包是一种优化应用加载性能的策略。通过将一些静态资源（如库文件、框架等）托管在 CDN 上，可以减少服务器负担，提高资源加载速度。
  1. 什么是 CDN？
  CDN（Content Delivery Network）是一种通过分布在不同地理位置的服务器网络来分发内容的技术。CDN 可以加速静态资源的加载，减少延迟，提高用户体验。

  2. 使用 CDN 的优势
  - 加速加载: CDN 服务器通常离用户更近，减少了网络延迟。
  - 减轻服务器负担: 将静态资源托管在 CDN 上，可以减少主服务器的流量和负载。
  - 高可用性: CDN 通常具有高冗余性和容错性，能够在某些节点失效时自动切换到其他节点。

  3. 在 Webpack 中配置 CDN
   1. 外部化依赖
  在 Webpack 配置中，可以使用 `externals` 属性将某些依赖标记为外部依赖，这样 Webpack 就不会将它们打包到最终的输出文件中，而是通过 CDN 加载。
   示例配置：
  const path = require('path');

  module.exports = {
      entry: './src/index.js',
      output: {
          filename: 'bundle.js',
          path: path.resolve(__dirname, 'dist'),
          publicPath: 'https://cdn.example.com/assets/' // 设置 CDN 基础路径
      },
      externals: {
          react: 'React', // 将 React 标记为外部依赖
          'react-dom': 'ReactDOM' // 将 ReactDOM 标记为外部依赖
      },
      mode: 'production',
  };

  在这个配置中，`publicPath` 设置了 CDN 的基础路径，而 `externals` 则指定了哪些库不需要打包，Webpack 会在生成的代码中使用全局变量（如 `React` 和 `ReactDOM`）来引用这些库。

   2. 引入 CDN 资源
  在 HTML 文件中，通过 `<script>` 标签引入 CDN 提供的库。例如：

  <!DOCTYPE html>
  <html lang="zh">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Webpack CDN 示例</title>
      <script src="https://cdn.example.com/react/17.0.2/umd/react.production.min.js"></script>
      <script src="https://cdn.example.com/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
  </head>
  <body>
      <div id="app"></div>
      <script src="bundle.js"></script>
  </body>
  </html>

  4. 注意事项
  - 版本管理: 确保使用的 CDN 资源版本与代码中引用的版本一致，以避免兼容性问题。
  - 网络依赖: 使用 CDN 依赖于网络，如果 CDN 服务不可用，可能会导致应用无法正常工作。因此，可以考虑在本地提供备份。
  - 安全性: 确保所使用的 CDN 资源是来自可信赖的来源，以避免安全风险。

  总结
  通过将某些静态资源托管在 CDN 上，可以显著提高 Webpack 应用的加载性能并减轻主服务器的负担。合理配置 Webpack 的 `externals` 和 `publicPath` 属性，结合 HTML 中的 CDN 引用，可以实现高效的资源管理和优化用户体验。希望这个总结对你理解 Webpack 分包与 CDN 服务器的使用有所帮助！
 */
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  mode: "production",
  devtool: false,
  entry: "./src/main.js",
  output: {
    clean: true,
    path: path.resolve(__dirname, "./build"),
    filename: "[name]_chunk.js",
  },
  /**
   * externals: 排除某些包不需要进行打包
   */
  externals: {
    /**
     * key属性名: 排除的框架名称
     * value属性值: 从CDN地址请求下来的js中提供对应的名称
     */
    react: "React",
    axios: "axios",
  },
  /**
   * resolve: 配置模块解析
   * extensions: 配置解析模块时自动补全的扩展名
   */
  resolve: {
    extensions: [".js", ".json", ".wasm", ".jsx", ".ts"],
  },
  devServer: {
    static: ["public", "content"],
    port: 3000,
    compress: true,
    proxy: [
      {
        context: () => true,
        target: "http://localhost:1234",
        pathRewrite: { "^/api": "" },
      },
    ],
    historyApiFallback: true,
  },
  optimization: {
    chunkIds: "deterministic", // 生成文件名时使用确定的文件名
    runtimeChunk: {
      name: "runtime", // 将runtime相关的代码单独打包
    },
    splitChunks: {
      // 分包配置
      chunks: "all", // 对所有模块都进行分割
      minSize: 10, // 分割的模块最小为10kb
      // 自己对需要进行拆包的内容进行分包
      cacheGroups: {
        utils: {
          test: /utils/,
          filename: "[id]_utils.js",
        },
        vendors: {
          // /node_modules/
          // window上面 /\
          // mac上面 /
          test: /[\\/]node_modules[\\/]/,
          filename: "[id]_vendors.js",
        },
      },
    },
    // 压缩配置
    minimizer: [
      new TerserPlugin({
        extractComments: false, // 不将注释提取到单独的文件中
      }),
    ],
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.js$/,
        use: "babel-loader",
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html", // 模板文件
    }),
  ],
};
